﻿using Newtonsoft.Json;
using System;
using System.IO;
using System.Windows.Forms;

namespace MockJson
{
    public partial class FrmEditResponse : Form
    {
        private readonly ApiResponse _editResponse;
        private readonly Action<ApiResponse> _action;

        public FrmEditResponse(ApiResponse editResponse, Action<ApiResponse> action)
        {
            InitializeComponent();

            cboContentType.Items.AddRange(new string[] { "application/json", "text/plain", "text/html" });
            cboContentType.SelectedIndex = 0;
            _editResponse = editResponse;
            _action = action;

            if (_editResponse != null)
            {
                txtResponse.Text = _editResponse.Response;
                cboContentType.Text = _editResponse.ContentType;
                cbEnable.Checked = _editResponse.Enable;
                numericWeight.Value = _editResponse.Weight;
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            var response = txtResponse.Text.Trim();

            if (string.IsNullOrEmpty(response))
            {
                txtResponse.Focus();
                return;
            }
            var contentType = cboContentType.Text;
            //Check Json
            if (contentType == "application/json")
            {
                var json = IsValidJson(response);
                if (!json)
                {
                    var dr = MessageBox.Show("您选择的是Json返回类型,但是返回值不是有效的Json字符串,是否继续?", "疑似错误", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                    if (dr != DialogResult.OK)
                    {
                        return;
                    }
                }
            }

            var _apiResponse = new ApiResponse()
            {
                ContentType = contentType,
                Enable = cbEnable.Checked,
                Response = response,
                Weight = (int)numericWeight.Value,
                Id = _editResponse?.Id ?? Guid.NewGuid().ToString()
            };
            _action.Invoke(_apiResponse);
            this.Close();
        }


        private static string FormatJsonString(string str)
        {
            try
            {
                JsonSerializer serializer = new JsonSerializer();
                TextReader tr = new StringReader(str);
                JsonTextReader jtr = new JsonTextReader(tr);
                object obj = serializer.Deserialize(jtr);
                if (obj != null)
                {
                    StringWriter textWriter = new StringWriter();
                    JsonTextWriter jsonWriter = new JsonTextWriter(textWriter)
                    {
                        Formatting = Formatting.Indented,
                        Indentation = 4,
                        IndentChar = ' '
                    };
                    serializer.Serialize(jsonWriter, obj);
                    return textWriter.ToString();
                }
                else
                {
                    return str;
                }
            }
            catch
            {
                return str;
            }
        }

        public bool IsValidJson(string strInput)
        {
            try
            {
                if (!strInput.StartsWith("[") && !strInput.StartsWith("{"))
                {
                    return false;
                }
                var json = JsonConvert.DeserializeObject<dynamic>(strInput);
                return true;
            }
            catch
            {
                return false;
            }
        }

        private void lblFormatJson_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            if (!IsValidJson(txtResponse.Text))
            {
                return;
            }
            txtResponse.Text = FormatJsonString(txtResponse.Text);
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}
